﻿using Cons.Domain.Entities.Cons;
using Cons.Service.JuheData.Base;
using Lynn.Domain.IRepository;
using Lynn.Infastructure.Extension;
using Lynn.Infastructure.Net.Http;
using Lynn.Infastructure.Utils;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Cons.Service.JuheData
{
    [AppService(AppServiceTargets.Scoped)]
    public class JuheService
    {
        IEFCoreRepository<ConsFortune> _repository;
        IEFCoreRepository<Constellation> _cons;
        IEFCoreRepository<FortuneRecord> _record;
        HttpWork _httpWork;

        public JuheService(IEFCoreRepository<ConsFortune> repository, IEFCoreRepository<Constellation> cons, IEFCoreRepository<FortuneRecord> record, HttpWork httpWork)
        {
            _repository = repository;
            _cons = cons;
            _record = record;
            _httpWork = httpWork;
        }

        /// <summary>
        /// 获取明天的运势数据
        /// </summary>
        /// <returns></returns>
        List<ConsFortune> LastConsFortune()
        {
            var mt = DateTime.Now.AddDays(1).Date;
            return _repository.Query(x => x.Date == mt).ToList();
        }
        public async Task InsertData()
        {
            var cons = await _cons.Query(x => true).ToListAsync();
            var olddatas = LastConsFortune();
            //获取基于明天的本地今年、本月、本周的运势
            var mt = DateTime.Now.AddDays(1).Date;
            var yearCode = mt.Year;
            var monthCode = mt.ToString("yyyyMM").ToInt();
            var weekCode = mt.AddDays(-(int)mt.DayOfWeek).ToString("yyyyMMdd").ToInt();
            var startTM = $"{mt.Year}-01-01".ToDateTime();
            var records = _record.Query(x => x.Date >= startTM).ToDictionary(x => x.Code, x => x);
            foreach (var con in cons)
            {
                var item = olddatas.Where(x => x.E_Cons == con.Code).FirstOrDefault();
                if (item != null)
                {
                    continue;
                }
                FortuneRecord year;
                FortuneRecord month;
                FortuneRecord week;
                var yearKey = $"{yearCode}{Convert.ToDouble(con.Code).ToString("00")}".ToInt();
                var monthKey = $"{monthCode}{Convert.ToDouble(con.Code).ToString("00")}".ToInt();
                var weekKey = $"{weekCode}{Convert.ToDouble(con.Code).ToString("00")}".ToInt();
                if (!records.TryGetValue(yearKey, out year))
                {
                    //获取年数据
                    year = await GetYear(con, yearKey, DateTime.Now.Date);
                    _record.InstertByCommit(year);
                }
                else {
                    _record.UpdateByCommit(year);
                }
                if (!records.TryGetValue(monthKey, out month))
                {
                    //获取月数据
                    month = await GetMonth(con, monthKey, DateTime.Now.Date);
                    _record.InstertByCommit(month);
                }
                else
                {
                    _record.UpdateByCommit(month);
                }
                if (!records.TryGetValue(weekKey, out week))
                {
                    //获取周数据
                    week = await GetWeek(con, weekKey, DateTime.Now.Date);
                    _record.InstertByCommit(week);
                }
                else
                {
                    _record.UpdateByCommit(week);
                }
                //获取天数据
                var key = $"{mt.ToString("yyyyMMdd")}{Convert.ToDouble(con.Code).ToString("00")}".ToInt();
                var data = await GetDay(con, key, mt);
                data.YearCode = year.Code;
                data.MonthCode = month.Code;
                data.WeekCode = week.Code;
                _repository.InstertByCommit(data);
            }
            await _repository.Commit();
        }

        private async Task<FortuneRecord> GetYear(Constellation con, int code, DateTime mt)
        {
            var url = $"{JuheOption.URL}&consName={con.Name}&type=year";
            var json = await _httpWork.Get(url);
            var yearinfo = JsonHelper.JsonToObject<YearInfo>(json);
            if (yearinfo.error_code != 0 || yearinfo.resultcode != 200)
            {
                return null;
            }
            if (yearinfo.year != mt.Year)
            {
                return null;
            }
            //组合数据
            var data = new FortuneRecord();
            data.Type = Domain.Entities.Enums.E_FortuneRecordType.年;
            data.Code = code;
            data.E_Cons = con.Code;
            data.Date = $"{mt.Year}-01-01".ToDateTime();
            data.Health = yearinfo.health.Length > 0 ? string.Join(',', yearinfo.health) : "";
            data.Work = yearinfo.career.Length > 0 ? string.Join(',', yearinfo.career) : "";
            data.Love = yearinfo.love.Length > 0 ? string.Join(',', yearinfo.love) : "";
            data.Money = yearinfo.finance.Length > 0 ? string.Join(',', yearinfo.finance) : "";
            data.LuckeyStone = yearinfo.luckeyStone;
            data.Summary = yearinfo.mima?.text.Length > 0 ? string.Join(',', yearinfo.mima?.text) : "";
            return data;
        }
        private async Task<FortuneRecord> GetMonth(Constellation con, int code, DateTime mt)
        {
            var url = $"{JuheOption.URL}&consName={con.Name}&type=month";
            var json = await _httpWork.Get(url);
            var info = JsonHelper.JsonToObject<MonthInfo>(json);
            if (info.error_code != 0 || info.resultcode != 200)
            {
                return null;
            }
            if (info.month != mt.Month) {
                return null;
            }
            //组合数据
            var data = new FortuneRecord();
            data.Type = Domain.Entities.Enums.E_FortuneRecordType.月;
            data.Code = code;
            data.Date = $"{mt.ToString("yyyy-MM")}-01".ToDateTime();
            data.Health = info.health;
            data.Work = info.work;
            data.Love = info.love;
            data.Money = info.money;
            data.E_Cons = con.Code;
            data.LuckeyStone = "";
            data.Summary = info.all;
            return data;
        }
        private async Task<FortuneRecord> GetWeek(Constellation con, int code, DateTime mt)
        {
            var url = $"{JuheOption.URL}&consName={con.Name}&type=week";
            var json = await _httpWork.Get(url);
            var info = JsonHelper.JsonToObject<WeekInfo>(json);
            if (info.error_code != 0 || info.resultcode != 200)
            {
                return null;
            }
            //组合数据
            var data = new FortuneRecord();
            data.Type = Domain.Entities.Enums.E_FortuneRecordType.周;
            data.Code = code;
            data.E_Cons = con.Code;
            data.Date = mt.AddDays(-(int)mt.DayOfWeek);
            data.Health = info.health;
            data.Work = info.work;
            data.Love = info.love;
            data.Money = info.money;
            data.LuckeyStone = "";
            data.Summary = "";
            return data;
        }
        private async Task<ConsFortune> GetDay(Constellation con, int code, DateTime mt)
        {
            var url = $"{JuheOption.URL}&consName={con.Name}&type=tomorrow";
            var json = await _httpWork.Get(url);
            json = json.Replace("QFriend", "friend");
            var info = JsonHelper.JsonToObject<DayInfo>(json);
            if (info.error_code != 0 || info.resultcode != 200)
            {
                return null;
            }
            if (info.date != mt.ToString("yyyyMMdd").ToInt())
            {
                return null;
            }
            //组合数据
            var data = info.ToObject<ConsFortune>();
            data.Code = code;
            data.E_Cons = con.Code;
            data.Date = mt;
            data.CalCode = mt.ToString("yyyyMMdd").ToInt();
            return data;
        }
    }

}
